package jedis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

import java.util.concurrent.TimeUnit;

public class JedisTransactions {

    public static void main(String[] args) {

        JedisTransactions jedisTransactions = new JedisTransactions();

//        jedisTransactions.transaction();
        jedisTransactions.transaction2();

    }

    /**
     * 事务回滚
     * 在执行事务时到100/0时程序会报错进入到catch里执行discard回滚
     */
    public void transaction() {
        //创建客户端连接服务端，redis服务端需要被开启
//        Jedis jedis = new Jedis("127.0.0.1", 6379);
        Jedis jedis = JedisUtil.getJedis();

        jedis.flushDB();

        //开启事务
        Transaction multi = jedis.multi();
        try{
            //向redis存入一条数据
            multi.set("key1", "value1");
            //再存入一条数据
            multi.set("key2", "value2");
            //这里引发了异常，用0作为被除数
            int i = 100/0;
            //如果没有引发异常，执行进入队列的命令
            multi.exec();
        }catch(Exception e){
            e.printStackTrace();
            //如果出现异常，回滚
            multi.discard();
        }finally{
            System.out.println(jedis.get("key1"));
            System.out.println(jedis.get("key2"));
            //最终关闭客户端
            jedis.close();
        }

        // 不执行100/0
        // value1, value2

        // 执行100/0
        // null, null

    }

    /**
     * watch
     */
    public void transaction2() {
        //创建客户端连接服务端，redis服务端需要被开启
//        Jedis jedis = new Jedis("127.0.0.1", 6379);
        Jedis jedis = JedisUtil.getJedis();

        jedis.flushDB();

        jedis.set("myKey","value");

        // 进行监视
        jedis.watch("myKey");

        //开启事务
        Transaction multi = jedis.multi();
        try{
            //修改
            multi.set("myKey", "valueMulti");

            //这里让程序睡眠20秒，在这20秒期间，用另一个客户端修改myKey的内容
            // 这里用window的客户端执行 set myKey xxx语句来模拟
            System.out.println("开始睡眠");
            TimeUnit.SECONDS.sleep(20);

            //如果没有引发异常，执行进入队列的命令
            multi.exec();
        }catch(Exception e){
            e.printStackTrace();
            //如果出现异常，回滚
            multi.discard();
        }finally{
            System.out.println(jedis.get("myKey")); // xxx
            //最终关闭客户端
            jedis.close();
        }

        // 客户端不执行
        // valueMulti
        // 客户端执行
        // xxx
    }

}
